##
#
#  <Test>
#    <TestType>DRT</TestType>
#    <Summary>Verifies the role-based security features</Summary>
#  </Test>
##
. (join-path $args[0] "..\Asserts.ps1")

Add-PsSnapin PsSpecCmdletManagement -ErrorAction SilentlyContinue
$testService = "http://localhost/cmdletdesigner/cmdlet.asmx"
$testDatasource = ".\SQLEXPRESS"
$testDatabase = "AspenManagement"
$username = "$env:USERDOMAIN\$env:USERNAME"
$sqlCommand = Resolve-Path (Join-Path $args[0] "Scripts\Invoke-SqlCommand.ps1")

function AssertArrayEquals
{
    param($expectedArray, $resultArray, $message)

    for($counter = 0; $counter -lt $expectedArray.Count; $counter++)
    {
        AssertEquals $expectedArray[$counter] $resultArray[$counter] ("$message #$counter. Expected {0}, Got {1}" -f $expectedArray[$counter],$resultArray[$counter])
    }
}

## Function to clear spec history
function ClearSpecHistory
{
    $clearSpecHistorySql = "DELETE FROM SpecHistory"
    [void] (& $sqlCommand $testDataSource $testDatabase $clearSpecHistorySql)
}


## Clean up protected project
$projectId = (Get-PsSpecProject TestProjectExistingProtectedProject* -Service $testService).Id
if($projectId) { [void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'") }
$projectId = (Get-PsSpecProject TestProjectExistingSharedProject* -Service $testService).Id
if($projectId) { [void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'") }
$projectId = (Get-PsSpecProject TestProjectExistingSpecWriterProject* -Service $testService).Id
if($projectId) { [void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'") }

AssertEquals 0 @(Get-PsSpecProject "TestProject*" -Service $testService).Count "Should have a fresh slate."
$error.Clear()

## Create shared projects

## -- Create a project owned by somebody else
& $sqlCommand $testDataSource $testDatabase "EXEC NewProject 'TestProjectExistingProtectedProject','An Existing protected Project','SECRETDOMAIN\leeholm'"
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectProtectedNoun','A protected noun','TestProjectExistingProtectedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectProtectedUnusedNounForDeletion','A protected unused noun for deletion','TestProjectExistingProtectedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectProtectedUnusedNoun','A protected unused noun for cmdlets','TestProjectExistingProtectedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewCmdlet @verb='Get',@noun='TestProjectProtectedNoun',@project='TestProjectExistingProtectedProject',@user='SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewParameter @parameterName='Existing',@cmdletName='Get-TestProjectProtectedNoun',@projectName='TestProjectExistingProtectedProject',@type='Int32',@description='',@aliases='',@allowGlobbing=0,@allowMultiple=0,@allowEmptyCollection=0,@allowEmptyString=0,@allowNull=0,@validateCount='',@validateNotNull=1,@validateNotNullOrEmpty=1,@validateRange='',@validateSet='',@validateLength='',@validatePattern='',@notes='',@isDynamic=1,@user='SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewProjectUser 'TestProjectExistingProtectedProject','SECRETDOMAIN\somebodyelse','ProjectOwner','SECRETDOMAIN\leeholm'")

## -- Create a project owned by somebody else, but shared to current user
& $sqlCommand $testDataSource $testDatabase "EXEC NewProject 'TestProjectExistingSharedProject','An Existing shared Project','SECRETDOMAIN\leeholm'"
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSharedNoun','A shared noun','TestProjectExistingSharedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSharedUnusedNounForDeletion','An unused shared noun for deletion','TestProjectExistingSharedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSharedUnusedNoun','An unused shared noun','TestProjectExistingSharedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewProjectUser 'TestProjectExistingSharedProject','$username','ProjectOwner','SECRETDOMAIN\leeholm'")

## -- Create a project owned by somebody else, but shared to current user as spec writer
& $sqlCommand $testDataSource $testDatabase "EXEC NewProject 'TestProjectExistingSpecWriterProject','An Existing shared spec writer Project','SECRETDOMAIN\leeholm'"
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSpecWriterNoun','A shared noun','TestProjectExistingSpecWriterProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSpecWriterUnusedNounForDeletion','An unused shared noun for deletion','TestProjectExistingSharedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectSpecWriterUnusedNoun','An unused shared noun','TestProjectExistingSpecWriterProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewProjectUser 'TestProjectExistingSpecWriterProject','$username','SpecWriter','SECRETDOMAIN\leeholm'")

## -- Create a project owned by somebody else, but shared to current user as help writer
& $sqlCommand $testDataSource $testDatabase "EXEC NewProject 'TestProjectExistingHelpWriterProject','An Existing shared help writer Project','SECRETDOMAIN\leeholm'"
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectHelpWriterNoun','A shared noun','TestProjectExistingHelpWriterProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectHelpWriterUnusedNounForDeletion','An unused shared noun for deletion','TestProjectExistingSharedProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewNoun 'TestProjectHelpWriterUnusedNoun','An unused shared noun','TestProjectExistingHelpWriterProject','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewProjectUser 'TestProjectExistingHelpWriterProject','$username','HelpWriter','SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewCmdlet @verb='Set',@noun='TestProjectHelpWriterUnusedNoun',@project='TestProjectExistingHelpWriterProject',@user='SECRETDOMAIN\leeholm'")
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC NewParameter @projectName='TestProjectExistingHelpWriterProject',@cmdletName='Set-TestProjectHelpWriterUnusedNoun',@parameterName='TestParameter',@type='String',@user='SECRETDOMAIN\leeholm'")

## Verify that project owners are listed as project users in the owner role
$user = Get-PsSpecUserPermission TestProjectExistingProtectedProject SECRETDOMAIN\leeholm -Service $testService
AssertEquals "ProjectOwner" $user.Role "Project owner should have a project owner role."

## Verify that shared project has two owners
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Service $testService).Count "Should have 2 owners"

## Verify that we cannot grant access to a project we don't own (at all)
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingProtectedProject -Service $testService).Count "Should have two owners of protected project"
Add-PsSpecUserPermission TestProjectExistingProtectedProject 'REDMOND\leeholm2' ProjectOwner -Service $testService -ErrorAction SilentlyContinue
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingProtectedProject -Service $testService).Count "Should still only have two owners of protected project"
AssertEquals 1 $error.Count "Should have generated an error trying to add to protected project"
$error.Clear()

## Verify that we cannot grant access to a project we don't own (as spec writer)
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSpecWriterProject -Service $testService).Count "Should have two owners of SpecWriter project"
Add-PsSpecUserPermission TestProjectExistingSpecWriterProject 'REDMOND\leeholm2' ProjectOwner -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated an error."
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSpecWriterProject -Service $testService).Count "Should still only have two owners of specwriter project"
$error.Clear()

ClearSpecHistory

## Verify that we can grant access to a project we own or co-own
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Service $testService).Count "Should only have two owners of shared project"
Add-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' ProjectOwner -Service $testService
AssertEquals 3 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Service $testService).Count "Should now have three users of shared project"
AssertEquals 0 $error.Count "Should not have generated an error trying to add to shared project"
$error.Clear()

## Verify the history entry wass added
$project = Get-PsSpecProject TestProjectExistingSharedProject -Service $testService
$history = @($project | Get-PsSpecHistory -ChangeType Project -Service $testService | ? { $_.PropertyName -eq "UserPermission"} )[0]
AssertEquals 'REDMOND\leeholm2 - ProjectOwner' $history.Notes


## Verify that we can grant access to a project we own or co-own
AssertEquals 3 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Service $testService).Count "Should only have three users of shared project"
Add-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' SpecWriter -Service $testService
AssertEquals 4 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Service $testService).Count "Should now have four owners (or users) of shared project"
AssertEquals 3 @(Get-PsSpecUserPermission TestProjectExistingSharedProject -Role ProjectOwner -Service $testService).Count "Should now have three owners of shared project"
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' -Service $testService).Count "Should now have two entries for REDMOND\leeholm2"
AssertEquals 0 $error.Count "Should not have generated an error trying to add to shared project"
$error.Clear()

## Verify that we cannot remove a user from a project we don't own (at all)
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingProtectedProject -Service $testService).Count "Should only have one owner of protected project"
Get-PsSpecUserPermission TestProjectExistingProtectedProject -Service $testService | Remove-PsSpecUserPermission -Service $testService -ErrorAction SilentlyContinue
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingProtectedProject -Service $testService).Count "Should still only have one owner of protected project"
AssertEquals 1 $error.Count "Should have generated an error trying to add to remove from protected project"
$error.Clear()

## Verify that we cannot remove a user from a project we don't own (as spec writer)
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSpecWriterProject -Service $testService).Count "Should have two owners of SpecWriter project"
Get-PsSpecUserPermission TestProjectExistingSpecWriterProject -Service $testService | Remove-PsSpecUserPermission -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated an error trying to remove from shared (as spec writer) project."
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSpecWriterProject -Service $testService).Count "Should still only have two owners of specwriter project"
$error.Clear()

ClearSpecHistory

## Verify that we can remove a user from a project we own or co-own
AssertEquals 2 @(Get-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' -Service $testService).Count "Should only have found new user"
Remove-PsSpecUserPermission -Project TestProjectExistingSharedProject -User 'REDMOND\leeholm2' -Role ProjectOwner -Service $testService
AssertEquals 1 @(Get-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' -Service $testService).Count "Should now have removed new user"
AssertEquals 1 @(Get-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' SpecWriter -Service $testService).Count "Should now have removed new user"
Remove-PsSpecUserPermission -Project TestProjectExistingSharedProject -User 'REDMOND\leeholm2' -Service $testService
AssertEquals 0 @(Get-PsSpecUserPermission TestProjectExistingSharedProject 'REDMOND\leeholm2' -Service $testService).Count "Should now have removed new user"
AssertEquals 0 $error.Count "Should not have generated an error trying to remove user"
$error.Clear()

## Validate the history
$project = Get-PsSpecProject TestProjectExistingSharedProject -Service $testService
$history = @($project | Get-PsSpecHistory -ChangeType Project -Service $testService | ? { $_.PropertyName -eq "UserPermission"} )
AssertEquals 2 $history.Count
AssertEquals 'REDMOND\leeholm2 - ProjectOwner' $history[0].Notes
AssertEquals 'REDMOND\leeholm2 - SpecWriter' $history[1].Notes

## Verify that we cannot update a project we don't own
Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService | Set-PsSpecProject -Name "TestProjectBrokenProject" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 @(Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService).Count "Should not have renamed project"
AssertEquals 1 $error.Count "Should have generated an error updating a protected project"
$error.Clear()

## Verify that we can update a shared project
Get-PsSpecProject TestProjectExistingSharedProject -Service $testService | Set-PsSpecProject -Name "TestProjectExistingSharedProjec2" -Service $testService
AssertEquals 0 @(Get-PsSpecProject TestProjectExistingSharedProject* -Service $testService).Count "Should have renamed shared project"
AssertEquals 1 @(Get-PsSpecProject TestProjectExistingSharedProjec2 -Service $testService).Count "Should have renamed shared project 2"
AssertEquals 0 $error.Count "Should not have generated an error updating a shared project"
Get-PsSpecProject TestProjectExistingSharedProjec2 -Service $testService | Set-PsSpecProject -Name "TestProjectExistingSharedProject" -Service $testService

## Verify that we can not add a noun to a project we don't own
AssertEquals 0 @(Get-PsSpecNoun TestProtectedNoun* -Project TestProjectExistingProtectedProject -Service $testService).Count "Protected project should have zero nouns"
[void] (New-PsSpecNoun TestProtectedNoun TestProtectedNounDescription TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue)
AssertEquals 1 $error.Count "Should have generated an error adding a noun to a protected project"
$error.Clear()
AssertEquals 0 @(Get-PsSpecNoun TestProtectedNoun* -Project TestProjectExistingProtectedProject -Service $testService).Count "Protected project should have zero nouns"

## Verify that we can add a noun to a shared project
AssertEquals 0 @(Get-PsSpecNoun TestSharedNoun* -Project TestProjectExistingSharedProject -Service $testService).Count "Shared project should not have noun"
[void] (New-PsSpecNoun TestSharedNoun TestSharedNounDescription TestProjectExistingSharedProject -Service $testService)
AssertEquals 0 $error.Count "Should not have generated an error adding a noun to a shared project"
AssertEquals 1 @(Get-PsSpecNoun TestSharedNoun -Project TestProjectExistingSharedProject -Service $testService).Count "Sharde project should now have 2 nouns"

## Verify that we cannot update a noun in a protected project
Get-PsSpecNoun TestProjectProtectedNoun -Project TestProjectExistingProtectedProject -Service $testService | 
    Set-PsSpecNoun -Name TestProjectProtectedNou2 -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated an error updating a noun from a protected project"
$error.Clear()
AssertEquals 1 @(Get-PsSpecNoun TestProjectProtectedNoun -Project TestProjectExistingProtectedProject -Service $testService).Count "Protected project should have one noun"

## Verify that we can update a noun in a shared project
Get-PsSpecNoun TestProjectSharedNoun -Project TestProjectExistingSharedProject -Service $testService | 
    Set-PsSpecNoun -Name TestProjectSharedNou2 -Service $testService
AssertEquals 0 $error.Count "Should not have generated an error updating a noun from a shared project"
$error.Clear()
AssertEquals 0 @(Get-PsSpecNoun TestProjectSharedNoun* -Project TestProjectExistingSharedProject -Service $testService).Count "Shared project should have no nouns"
AssertEquals 1 @(Get-PsSpecNoun TestProjectSharedNou2 -Project TestProjectExistingSharedProject -Service $testService).Count "Shared project should have one new noun"
Get-PsSpecNoun TestProjectSharedNou2 -Project TestProjectExistingSharedProject -Service $testService | 
    Set-PsSpecNoun -Name TestProjectSharedNoun -Service $testService

## Verify that we cannot update a noun if you don't have the rights to all projects that
## depend upon it


## Verify that we cannot remove a noun from a protected project
Get-PsSpecNoun TestProjectProtectedUnusedNounForDeletion -Project TestProjectExistingProtectedProject -Service $testService | 
    Remove-PsSpecNoun -Service $testService -ErrorAction SilentlyContinue -Force
AssertEquals 1 $error.Count "Should have generated an error removing a noun from a protected project"
$error.Clear()
AssertEquals 1 @(Get-PsSpecNoun TestProjectProtectedUnusedNounForDeletion -Project TestProjectExistingProtectedProject -Service $testService).Count "Protected project should have one noun"

## Verify that we can remove a noun from a shared project
Get-PsSpecNoun TestProjectSharedUnusedNounForDeletion -Project TestProjectExistingSharedProject -Service $testService | 
    Remove-PsSpecNoun -Service $testService -Force
AssertEquals 0 $error.Count "Should not have generated an error removing a noun from a shared project"
$error.Clear()
AssertEquals 0 @(Get-PsSpecNoun TestProjectSharedUnusedNounForDeletion* -Project TestProjectExistingSharedProject -Service $testService).Count "Shared project should no longer have noun"

## Verify that we cannot add a cmdlet to a protected project
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectProtectedUnusedNoun* TestProjectExistingProtectedProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should not have found protected cmdlet"
$error.Clear()
[void] (New-PsSpecCmdlet -Snapin FooSnapin -Verb Set -Noun TestProjectProtectedUnusedNoun -Project TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectProtectedUnusedNoun* TestProjectExistingProtectedProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should not have created protected cmdlet"
$error.Clear()
 
## Verify that we can add a cmdlet to a shared project (as co-owner)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingSharedProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should not have found shared cmdlet"
$error.Clear()
[void] (New-PsSpecCmdlet -Snapin FooSnapin -Verb Set -Noun TestProjectSharedUnusedNoun -Project TestProjectExistingSharedProject -Service $testService)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingSharedProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should have created protected cmdlet"
$error.Clear()

## Verify that we can add a cmdlet to a shared project (as spec writer)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should not have found SpecWriter cmdlet"
$error.Clear()
[void] (New-PsSpecCmdlet -Snapin FooSnapin -Verb Set -Noun TestProjectSpecWriterUnusedNoun -Project TestProjectExistingSpecWriterProject -Service $testService)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should have created SpecWriter cmdlet"
$error.Clear()


## Verify that we cannot update a cmdlet from a protected project
$cmdlet = @(Get-PsSpecCmdlet Get-TestProjectProtectedNoun* TestProjectExistingProtectedProject -Service $testService)[0]
AssertEquals $null $cmdlet.ShortDescription
$cmdlet | Set-PsSpecCmdlet -ShortDescription "Test" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$cmdlet = @(Get-PsSpecCmdlet Get-TestProjectProtectedNoun* TestProjectExistingProtectedProject -Service $testService)[0]
AssertEquals $null $cmdlet.ShortDescription
$error.Clear()
 
## Verify that we can update a cmdlet from a shared project (as co-owner)
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingSharedProject -Service $testService)[0]
AssertEquals $null $cmdlet.ShortDescription
$cmdlet | Set-PsSpecCmdlet -ShortDescription "Test" -Service $testService
AssertEquals 0 $error.Count "Should not have generated errors"
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingSharedProject -Service $testService)[0]
AssertEquals "Test" $cmdlet.ShortDescription
$error.Clear()

## Verify that we can update a cmdlet from a shared project (as spec writer)
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)[0]
AssertEquals $null $cmdlet.ShortDescription
$cmdlet | Set-PsSpecCmdlet -ShortDescription "Test" -Service $testService
AssertEquals 0 $error.Count "Should not have generated errors"
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)[0]
AssertEquals "Test" $cmdlet.ShortDescription
$error.Clear()

## Verify that a spec writer cannot update cmdlet help details they are restricted from
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)[0]
AssertEquals $null $cmdlet.HelpShortDescription
AssertEquals $null $cmdlet.HelpLongtDescription
AssertEquals $null $cmdlet.HelpInputObjectDescription
AssertEquals $null $cmdlet.HelpOutputObjectDescription
AssertEquals $null $cmdlet.HelpAdditionalNotes
AssertEquals $null $cmdlet.HelpStatus
AssertEquals 0 @($cmdlet.HelpExamples).Length
$cmdlet | Set-PsSpecCmdlet -HelpShortDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpLongDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpInputObjectDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpOutputObjectDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpAdditionalNotes "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpStatus "Test" -Service $testService -ErrorAction SilentlyContinue

$helpExample1 = New-Object Microsoft.PowerShell.CmdletManagement.PsSpecHelpExample
$helpExample1.Command = "Get-Process123"
$helpExample1.Output = "... Processes ..."
$helpExample1.Description = "This command outputs some processes."

$helpExample2 = New-Object Microsoft.PowerShell.CmdletManagement.PsSpecHelpExample
$helpExample2.Command = "Get-Process2123"
$helpExample2.Output = "... Processes ...2"
$helpExample2.Description = "This command outputs some processes.2"

$cmdlet | Set-PsSpecCmdlet -HelpExamples $helpExample1,$helpExample2 -Service $testService -ErrorAction SilentlyContinue
AssertEquals 0 $error.Count "Failure to update disallowed help fields should not generate an error"

$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)[0]
AssertEquals $null $cmdlet.HelpShortDescription
AssertEquals $null $cmdlet.HelpLongtDescription
AssertEquals $null $cmdlet.HelpInputObjectDescription
AssertEquals $null $cmdlet.HelpOutputObjectDescription
AssertEquals $null $cmdlet.HelpAdditionalNotes
AssertEquals $null $cmdlet.HelpStatus
AssertEquals 0 @($cmdlet.HelpExamples).Length
$error.Clear()

## Verify that a spec writer cannot update parameter help details they are restricted from
Add-PsSpecCmdletParameter -Project TestProjectExistingSpecWriterProject -Cmdlet Set-TestProjectSpecWriterUnusedNoun -Name TestParameter -Type String -Service $testService
$parameter = Get-PsSpecCmdletParameter -Project TestProjectExistingSpecWriterProject -CmdletName Set-TestProjectSpecWriterUnusedNoun -Name TestParameter -Service $testService
AssertEquals $null $parameter.HelpDescription "Parameter HelpDescription"
$parameter | Set-PsSpecCmdletParameter -HelpDescription "Test" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 0 $error.Count "Failure to update disallowed help fields should not generate an error"
$parameter = Get-PsSpecCmdletParameter -Project TestProjectExistingSpecWriterProject -CmdletName Set-TestProjectSpecWriterUnusedNoun -Name TestParameter -Service $testService
AssertEquals $null $parameter.HelpDescription "Parameter HelpDescription"
$error.Clear()

## Verify that a help writer cannot update cmdlet details they are restricted from, but can update
## appropriate properties
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectHelpWriterUnusedNoun* TestProjectExistingHelpWriterProject -Service $testService)[0]
AssertEquals $null $cmdlet.Snapin
AssertEquals "Set" $cmdlet.Verb
AssertEquals "TestProjectHelpWriterUnusedNoun" $cmdlet.Noun
AssertEquals $null $cmdlet.TeamMembers
AssertEquals $null $cmdlet.ShortDescription
AssertEquals $null $cmdlet.LongDescription
AssertEquals $false $cmdlet.SupportsShouldProcess
AssertEquals $null $cmdlet.Notes
AssertEquals $null $cmdlet.SpecExamples
AssertEquals $null $cmdlet.OutputObject
AssertEquals $null $cmdlet.OutputObjectDescription
AssertEquals $null $cmdlet.RelatedTo
AssertEquals $null $cmdlet.DefaultParameterSetName
AssertEquals $null $cmdlet.Custom1
AssertEquals $null $cmdlet.Custom2
AssertEquals $null $cmdlet.Custom3
AssertEquals $null $cmdlet.Custom4
AssertEquals $null $cmdlet.Status
AssertEquals $null $cmdlet.HelpStatus
AssertEquals $null $cmdlet.HelpShortDescription
AssertEquals $null $cmdlet.HelpLongDescription
AssertEquals $null $cmdlet.InputObject
AssertEquals $null $cmdlet.HelpInputObjectDescription
AssertEquals $null $cmdlet.HelpOutputObjectDescription
AssertEquals $null $cmdlet.HelpAdditionalNotes
$cmdlet | Set-PsSpecCmdlet -Snapin "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Verb "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Noun "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -TeamMembers "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -ShortDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -LongDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -SupportsShouldProcess $true -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Notes "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -SpecExamples "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -OutputObject "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -OutputObjectDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -RelatedTo "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -DefaultParameterSetName "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Custom1 "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Custom2 "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Custom3 "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Custom4 "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -Status "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpStatus "Test" -Service $testService -ErrorAction SilentlyContinue

$helpExample1 = New-Object Microsoft.PowerShell.CmdletManagement.PsSpecHelpExample
$helpExample1.Command = "Get-Process"
$helpExample1.Output = "... Processes ..."
$helpExample1.Description = "This command outputs some processes."

$helpExample2 = New-Object Microsoft.PowerShell.CmdletManagement.PsSpecHelpExample
$helpExample2.Command = "Get-Process2"
$helpExample2.Output = "... Processes ...2"
$helpExample2.Description = "This command outputs some processes.2"

$cmdlet | Set-PsSpecCmdlet -HelpExamples $helpExample1,$helpExample2 -Service $testService -ErrorAction SilentlyContinue

## Refresh the cmdlet here so we don't delete the help examples as we continue
$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectHelpWriterUnusedNoun* TestProjectExistingHelpWriterProject -Service $testService)[0]

$cmdlet | Set-PsSpecCmdlet -HelpShortDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpLongDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -InputObject "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpInputObjectDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpOutputObjectDescription "Test" -Service $testService -ErrorAction SilentlyContinue
$cmdlet | Set-PsSpecCmdlet -HelpAdditionalNotes "Test" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 0 $error.Count "Failure to update disallowed cmdlet fields should not generate an error"

$cmdlet = @(Get-PsSpecCmdlet Set-TestProjectHelpWriterUnusedNoun* TestProjectExistingHelpWriterProject -Service $testService)[0]

AssertEquals $null $cmdlet.Snapin "Snapin"
AssertEquals "Set" $cmdlet.Verb "Verb"
AssertEquals "TestProjectHelpWriterUnusedNoun" $cmdlet.Noun "Noun"
AssertEquals $null $cmdlet.TeamMembers
AssertEquals $null $cmdlet.ShortDescription "ShortDescription"
AssertEquals $null $cmdlet.LongDescription "LongDescription"
AssertEquals $false $cmdlet.SupportsShouldProcess "SupportsShouldProcess"
AssertEquals $null $cmdlet.Notes "Notes"
AssertEquals $null $cmdlet.SpecExamples "SpecExamples"
AssertEquals "Test" $cmdlet.OutputObject "OutputObject"
AssertEquals $null $cmdlet.OutputObjectDescription "OutputObjectDescription"
AssertEquals "Test" $cmdlet.RelatedTo "RelatedTo"
AssertEquals $null $cmdlet.DefaultParameterSetName "DefaultParameterSetName"
AssertEquals $null $cmdlet.Custom1 "Custom1"
AssertEquals $null $cmdlet.Custom2 "Custom2"
AssertEquals $null $cmdlet.Custom3 "Custom3"
AssertEquals $null $cmdlet.Custom4 "Custom4"
AssertEquals $null $cmdlet.Status "Status"
AssertEquals "Test" $cmdlet.HelpStatus "HelpStatus"

AssertEquals 2 $cmdlet.HelpExamples.Length "HelpExamples"

AssertEquals "Test" $cmdlet.HelpShortDescription "HelpShortDescription"
AssertEquals "Test" $cmdlet.HelpLongDescription "HelpLongDescription"
AssertEquals "Test" $cmdlet.InputObject "InputObject"
AssertEquals "Test" $cmdlet.HelpInputObjectDescription "HelpInputObjectDescription"
AssertEquals "Test" $cmdlet.HelpOutputObjectDescription "HelpOutputObjectDescription"
AssertEquals "Test" $cmdlet.HelpAdditionalNotes "HelpAdditionalNotes"
$error.Clear()

## Verify that a help writer cannot update parameter details they are restricted from
$parameter = Get-PsSpecCmdletParameter -Project TestProjectExistingHelpWriterProject -CmdletName Set-TestProjectHelpWriterUnusedNoun -Name TestParameter -Service $testService

AssertEquals "TestParameter" $parameter.Name "ParameterName"
AssertEquals "String" $parameter.Type "ParameterType"
AssertEquals $null $parameter.Description "Description"
AssertEquals $null $parameter.Alias "Alias"
AssertEquals $false $parameter.AllowGlobbing "AllowGlobbing"
AssertEquals $false $parameter.AllowMultiple "AllowMultiple"
AssertEquals $false $parameter.IsDynamic "Dynamic"
AssertEquals $false $parameter.AllowEmptyCollection "AllowEmptyCollection"
AssertEquals $false $parameter.AllowEmptyString "AllowEmptyString"
AssertEquals $false $parameter.AllowNull "AllowNull"
AssertEquals $null $parameter.ValidateCount "ValidateCount"
AssertEquals $true $parameter.ValidateNotNull "ValidateNotNull"
AssertEquals $true $parameter.ValidateNotNullOrEmpty "ValidateNotNullOrEmpty"
AssertEquals $null $parameter.ValidateRange "ValidateRange"
AssertEquals $null $parameter.ValidateSet "ValidateSet"
AssertEquals $null $parameter.ValidateLength "ValidateLength"
AssertEquals $null $parameter.ValidatePattern "ValidatePattern"
AssertEquals $null $parameter.Notes "Note"
AssertEquals $null $parameter.DefaultValue "Parameter DefaultValue"
AssertEquals $null $parameter.Custom1 "Parameter Custom1"
AssertEquals $null $parameter.Custom2 "Parameter Custom2"
AssertEquals $null $parameter.Custom3 "Parameter Custom3"
AssertEquals $null $parameter.Custom4 "Parameter Custom4"
AssertEquals $null $parameter.HelpDescription "Parameter HelpDescription"

$parameter | Set-PsSpecCmdletParameter `
    -Type Int `
    -Alias "Id","PID" `
    -Description "Some Description" `
    -AllowGlobbing:$true `
    -AllowMultiple:$true `
    -Dynamic:$false `
    -AllowEmptyCollection:$false `
    -AllowEmptyString:$false `
    -AllowNull:$false `
    -ValidateCount 1,10 `
    -ValidateNotNull:$true `
    -ValidateNotNullOrEmpty:$true `
    -ValidateRange 0,99999 `
    -ValidateSet "These","Will","Not","Be","Used" `
    -ValidateLength 1,500 `
    -ValidatePattern "foo.*[a-zA-Z0-9]*" `
    -Notes "This is a note about the parameter" `
    -DefaultValue "DefaultValue" `
    -Custom1 "Custom1" `
    -Custom2 "Custom2" `
    -Custom3 "Custom3" `
    -Custom4 "Custom4" `
    -HelpDescription "HelpDescription" `
    -ServiceUri $testService

AssertEquals 0 $error.Count "Failure to update disallowed help fields should not generate an error"
$parameter = Get-PsSpecCmdletParameter -Project TestProjectExistingHelpWriterProject -CmdletName Set-TestProjectHelpWriterUnusedNoun -Name TestParameter -Service $testService

Assertequals "TestParameter" $parameter.Name "ParameterName2"
AssertEquals "String" $parameter.Type "ParameterType2"
AssertEquals $null $parameter.Description "Description2"
AssertEquals $null $parameter.Alias "Alias2"
AssertEquals $true $parameter.AllowGlobbing "AllowGlobbing2"
AssertEquals $false $parameter.AllowMultiple "AllowMultiple2"
AssertEquals $false $parameter.IsDynamic "Dynamic2"
AssertEquals $false $parameter.AllowEmptyCollection "AllowEmptyCollection2"
AssertEquals $false $parameter.AllowEmptyString "AllowEmptyString2"
AssertEquals $false $parameter.AllowNull "AllowNull2"
AssertEquals $null $parameter.ValidateCount "ValidateCount2"
AssertEquals $true $parameter.ValidateNotNull "ValidateNotNull2"
AssertEquals $true $parameter.ValidateNotNullOrEmpty "ValidateNotNullOrEmpty2"
AssertEquals $null $parameter.ValidateRange "ValidateRange2"
AssertEquals $null $parameter.ValidateSet "ValidateSet2"
AssertEquals $null $parameter.ValidateLength "ValidateLength2"
AssertEquals $null $parameter.ValidatePattern "ValidatePattern2"
AssertEquals $null $parameter.Notes "Note2"
AssertEquals "DefaultValue" $parameter.DefaultValue "Parameter DefaultValue2"
AssertEquals $null $parameter.Custom1 "Parameter Custom12"
AssertEquals $null $parameter.Custom2 "Parameter Custom22"
AssertEquals $null $parameter.Custom3 "Parameter Custom32"
AssertEquals $null $parameter.Custom4 "Parameter Custom42"
AssertEquals "HelpDescription" $parameter.HelpDescription "Parameter HelpDescription2"

$error.Clear()


## Verify that we cannot add a parameter to a cmdlet in a protected project
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Get-TestProjectProtectedNoun* -ProjectName TestProjectExistingProtectedProject -Service $testService)
AssertEquals 0 $parameters.Count
Add-PsSpecCmdletParameter -Name Test -Type Int32  -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -ErrorAction SilentlyContinue -Service $testService
AssertEquals 1 $error.Count "Should have generated errors"
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Get-TestProjectProtectedNoun* -ProjectName TestProjectExistingProtectedProject -Service $testService)
AssertEquals 0 $parameters.Count
$error.Clear()

## Verify that we can add a parameter to a cmdlet in a shared project (as co-owner)
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun* -ProjectName TestProjectExistingSharedProject -Service $testService)
AssertEquals 0 $parameters.Count
Add-PsSpecCmdletParameter -Name Test -Type Int32  -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun* -ProjectName TestProjectExistingSharedProject -Service $testService)
AssertEquals 1 $parameters.Count
$error.Clear()

## Verify that we can add a parameter to a cmdlet in a shared project (as spec writer)
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun* -ProjectName TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 0 $parameters.Count
Add-PsSpecCmdletParameter -Name Test -Type Int32  -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun* -ProjectName TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 1 $parameters.Count
$error.Clear()


## Verify that we cannot update a parameter in a protected project
$parameter = Get-PsSpecCmdletParameter -Name Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService
AssertEquals "Existing" $parameter.Name
AssertEquals $null $parameter.Description
$parameter | Set-PsSpecCmdletParameter -Description "Updated Description" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$parameter = Get-PsSpecCmdletParameter -Name Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService
AssertEquals $null $parameter.Description
$error.Clear()

## Verify that we can update a parameter in a shared project (as co-owner)
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals $null $parameter.Description
AssertEquals "Test" $parameter.Name
$parameter | Set-PsSpecCmdletParameter -Description "Updated Description" -Service $testService
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "Updated Description" $parameter.Description
$error.Clear()

## Verify that we can update a parameter in a shared project (as spec writer)
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals $null $parameter.Description
AssertEquals "Test" $parameter.Name
$parameter | Set-PsSpecCmdletParameter -Description "Updated Description" -Service $testService
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "Updated Description" $parameter.Description
$error.Clear()


## Verify that we cannot add a parameter set entry to a cmdlet in a protected project
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue
AssertEquals $null $parameterSetEntry
Add-PsSpecCmdletParameterSetEntry -ProjectName TestProjectExistingProtectedProject -CmdletName Get-TestProjectProtectedNoun -ParameterName Existing -ParameterSetName NonExistingSet -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue
AssertEquals $null $parameterSetEntry
$error.Clear()

## Verify that we can add a parameter set entry to a cmdlet in a shared project (as co-owner)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals $null $parameterSetEntry
Add-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "NonExistingSet" $parameterSetEntry.ParameterSetName
$error.Clear()

## Verify that we can add a parameter set entry to a cmdlet in a shared project (as spec writer)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals $null $parameterSetEntry
Add-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "NonExistingSet" $parameterSetEntry.ParameterSetName
$error.Clear()

## Verify that we cannot edit a parameter set entry of a cmdlet in a protected project
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue
AssertEquals $null $parameterSetEntry.ParameterSetName
$parameterSetEntry | Set-PsSpecCmdletParameterSetEntry -ParameterSetName "Moved" -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue
AssertEquals $null $parameterSetEntry.ParameterSetName
$error.Clear()

## Verify that we can edit a parameter set entry of a cmdlet in a shared project (as co-owner)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "NonExistingSet" $parameterSetEntry.ParameterSetName
$parameterSetEntry | Set-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -Service $testService
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "NewSet" $parameterSetEntry.ParameterSetName
$error.Clear()

## Verify that we can edit a parameter set entry of a cmdlet in a shared project (as spec writer)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NonExistingSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "NonExistingSet" $parameterSetEntry.ParameterSetName
$parameterSetEntry | Set-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -Service $testService
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "NewSet" $parameterSetEntry.ParameterSetName
$error.Clear()


## Verify that we cannot delete a parameter set entry of a cmdlet in a protected project
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue
AssertEquals $null $parameterSetEntry.ParameterSetName
$parameterSetEntry | Remove-PsSpecCmdletParameterSetEntry -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$parameterSetEntry = @(Get-PsSpecCmdletParameterSetEntry -ParameterName Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService -ErrorAction SilentlyContinue)
AssertEquals 1 $parameterSetEntry.Count
$error.Clear()

## Verify that we can delete a parameter set entry of a cmdlet in a shared project (as co-owner)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "NewSet" $parameterSetEntry.ParameterSetName
$parameterSetEntry | Remove-PsSpecCmdletParameterSetEntry -Service $testService
$parameterSetEntry = @(Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet* -ParameterName Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService)
AssertEquals 0 $parameterSetEntry.Count
$error.Clear()

## Verify that we can delete a parameter set entry of a cmdlet in a shared project (as spec writer)
$parameterSetEntry = Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "NewSet" $parameterSetEntry.ParameterSetName
$parameterSetEntry | Remove-PsSpecCmdletParameterSetEntry -Service $testService
$parameterSetEntry = @(Get-PsSpecCmdletParameterSetEntry -ParameterSetName NewSet* -ParameterName Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 0 $parameterSetEntry.Count
$error.Clear()


## Verify that we cannot remove a parameter from a protected project
$parameter = Get-PsSpecCmdletParameter -Name Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService
AssertEquals "Existing" $parameter.Name
$parameter | Remove-PsSpecCmdletParameter -Service $testService -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$parameter = Get-PsSpecCmdletParameter -Name Existing -CmdletName Get-TestProjectProtectedNoun -ProjectName TestProjectExistingProtectedProject -Service $testService
AssertEquals "Existing" $parameter.Name
$error.Clear()

## Verify that we can remove a parameter from a shared project (as co-owner)
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService
AssertEquals "Test" $parameter.Name
$parameter | Remove-PsSpecCmdletParameter -Service $testService
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSharedUnusedNoun -ProjectName TestProjectExistingSharedProject -Service $testService)
AssertEquals 0 $parameters.Count
$error.Clear()

## Verify that we can remove a parameter from a shared project (as spec writer)
$parameter = Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService
AssertEquals "Test" $parameter.Name
$parameter | Remove-PsSpecCmdletParameter -Service $testService
$parameters = @(Get-PsSpecCmdletParameter -Name Test -CmdletName Set-TestProjectSpecWriterUnusedNoun -ProjectName TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 0 $parameters.Count
$error.Clear()

## Verify that we cannot remove a cmdlet from a protected project
$cmdlets = @(Get-PsSpecCmdlet Get-TestProjectProtectedNoun* TestProjectExistingProtectedProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should have found protected cmdlet"
$error.Clear()
$cmdlets | Remove-PsSpecCmdlet -Service $testService -Force -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated errors"
$cmdlets = @(Get-PsSpecCmdlet Get-TestProjectProtectedNoun* TestProjectExistingProtectedProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should not have deleted protected cmdlet"
$error.Clear()
 
## Verify that we can remove a cmdlet from a shared project (as co-owner)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingSharedProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should have found shared cmdlet"
$error.Clear()
$cmdlets | Remove-PsSpecCmdlet -Service $testService -Force
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSharedUnusedNoun* TestProjectExistingProtectedProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should have removed shared cmdlet"
$error.Clear()

## Verify that we can remove a cmdlet from a shared project (as spec writer)
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 1 $cmdlets.Count "Should have found SpecWriter cmdlet"
$error.Clear()
$cmdlets | Remove-PsSpecCmdlet -Service $testService -Force
$cmdlets = @(Get-PsSpecCmdlet Set-TestProjectSpecWriterUnusedNoun* TestProjectExistingSpecWriterProject -Service $testService)
AssertEquals 0 $cmdlets.Count "Should have removed SpecWriter cmdlet"
$error.Clear()

## Verify that we cannot remove somebody else's protected project
$error.Clear()
AssertEquals 1 @(Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService).Count
Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService | Remove-PsSpecProject -Service $testService -Force -ErrorAction SilentlyContinue
AssertEquals 1 $error.Count "Should have generated an error trying to remove protected project"
$error.Clear()
AssertEquals 1 @(Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService).Count

## Verify that we can remove somebody else's shared project
AssertEquals 1 @(Get-PsSpecProject TestProjectExistingSharedProject* -Service $testService).Count
Get-PsSpecProject TestProjectExistingSharedProject -Service $testService | Remove-PsSpecProject -Service $testService -Force
AssertEquals 0 $error.Count "Should not have generated an error trying to remove shared project"
AssertEquals 0 @(Get-PsSpecProject TestProjectExistingSharedProject* -Service $testService).Count

## Clean up protected project
$projectId = (Get-PsSpecProject TestProjectExistingProtectedProject -Service $testService).Id
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'")
$projectId = (Get-PsSpecProject TestProjectExistingSpecWriterProject -Service $testService).Id
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'")
$projectId = (Get-PsSpecProject TestProjectExistingHelpWriterProject -Service $testService).Id
[void] (& $sqlCommand $testDataSource $testDatabase "EXEC RemoveProject '$projectId','SECRETDOMAIN\leeholm'")

ClearSpecHistory

## Verify we're at a clean slate
$projects = @(Get-PsSpecProject "TestProject*" -Service $testService)
AssertEquals 0 $projects.Count "Should have removed projects and dependencies."
